' CountDownClock.BAS
'====================================================================
'
' DIGITAL.BAS for PowerBASIC Compiler for Windows
' Copyright (c) 2005-2011 PowerBASIC, Inc.
' All Rights Reserved.
'
' Shows how to use GRAPHIC COPY to copy desired parts from a bitmap
' to create a "fancy" digital clock.
'
'====================================================================
#COMPILER PBWIN 10
#COMPILE EXE
#DIM ALL
#RESOURCE BITMAP 100, "BIG_Digits2.bmp"
#INCLUDE ONCE "WIN32API.INC"
%ID_TIMER1 = 100
%IDC_GRAPHIC1 = 120
$TargetDate = "13/06/2024" ' set a target date in dd/MM/yyyy format
'====================================================================
FUNCTION PBMAIN () AS LONG
'--------------------------------------------------------------------
' PROGRAM ENTRANCE
' The dialog is created with Pixels option, which gives its child
' controls a pixel coordinates system. Exstyle& %WS_EX_TOPMOST is
' set to make it float on top and %WS_EX_TOOLWINDOW gives it a
' smaller Caption height, plus hides it from the taskbar.
'------------------------------------------------------------------
LOCAL hDlg AS DWORD
DIALOG NEW PIXELS, 0, " Digital",,, 680, 120, _
%WS_CAPTION OR %WS_SYSMENU, _
%WS_EX_TOOLWINDOW OR %WS_EX_TOPMOST TO hDlg
DIALOG SET COLOR hDlg, %BLACK, %BLACK
'------------------------------------------------------------------
CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 0, 0, 680, 120
GRAPHIC ATTACH hDlg, %IDC_GRAPHIC1, REDRAW
GRAPHIC CLEAR %BLACK
'------------------------------------------------------------------
DIALOG SHOW MODAL hDlg, CALL DlgProc
END FUNCTION
'====================================================================
CALLBACK FUNCTION DlgProc() AS LONG
'--------------------------------------------------------------------
' MAIN DIALOG'S CALLBACK PROCEDURE
' A 3000 ms (30 sec.) timer is created under %WM_INITDIALOG
' and it will trigger a %WM_TIMER message every 0.5 second,
'------------------------------------------------------------------
LOCAL ac, c AS LONG, sTime AS STRING
SELECT CASE CB.MSG
CASE %WM_INITDIALOG ' <- sent right before the dialog is displayed.
STATIC hBmp AS DWORD ' Static bitmap handle
STATIC idEvent AS LONG ' Keep SetTimer's result in a static variable
idEvent = SetTimer(CB.HNDL, %ID_TIMER1, _ ' Create WM_TIMER events with the SetTimer API
30000, BYVAL %NULL) ' at 500 ms (0.5 s) interval
GRAPHIC BITMAP LOAD "#100", _ ' load bitmap strip with digits
840, 120 TO hBmp
DIALOG POST CB.HNDL, %WM_TIMER, %ID_TIMER1, 0 ' force an initial %WM_TIMER "event"
CASE %WM_TIMER ' Posted by the created timer
IF CB.WPARAM = %ID_TIMER1 THEN ' Make sure it's corrent timer id
sTime = funGetCountDown() ' grab time string (00:00:00)
FOR c = 1 TO LEN(sTime) ' parse through it
ac = ASC(sTime, c) ' look at ASCII code for each character
SELECT CASE AS LONG ac ' copy bitmap parts via lookup "table"
CASE 48 TO 57 ' digits 0 to 9
ac = ac - 48 ' make the value zero-based and copy bmp part
GRAPHIC COPY hBmp, 0, (ac * 60, 0)-(ac * 60 + 58, 80) TO ((c - 1) * 60, 40)
' CASE 58 ' colon is the 13th image in the Bmp strip
' GRAPHIC COPY hBmp, 0, (12 * 60, 0)-(12 * 60 + 60, 80) TO ((c - 1) * 60, 0)
END SELECT
NEXT
GRAPHIC COPY hBmp,0,(0,80)-(680,120) TO (0,0)
GRAPHIC REDRAW ' Now we can redraw it all
END IF
CASE %WM_DESTROY ' Sent when the dialog is being destroyed
IF idEvent THEN ' If a timer identifier exists
KillTimer CB.HNDL, idEvent ' make sure to stop the timer events
END IF
GRAPHIC ATTACH hBmp, 0 ' clean up memory
GRAPHIC BITMAP END
CASE %WM_COMMAND ' <- A control is calling
SELECT CASE CB.CTL ' <- Look at control's id
CASE %IDCANCEL
IF CB.CTLMSG = %BN_CLICKED THEN ' Exit on Esc
DIALOG END CB.HNDL
END IF
END SELECT
END SELECT
END FUNCTION
'
FUNCTION funGetCountDown() AS STRING
' return Months - Days - Hours - minutes
' countdown
' $TargetDate in dd/MM/yyyy format
LOCAL strResult AS STRING ' result to be returned
' prep the current date/time
LOCAL DateCalc AS IPOWERTIME
LET DateCalc = CLASS "PowerTime"
DateCalc.Now ' set to now
'
' prep the future data/time
LOCAL FutureDate AS IPOWERTIME
LET FutureDate = CLASS "PowerTime"
'
' create local vars to hold year/month/day
LOCAL lngYear AS LONG
LOCAL lngMonth AS LONG
LOCAL lngDay AS LONG
'
' store future date
lngYear = VAL(RIGHT$($TargetDate,4))
lngMonth = VAL(MID$($TargetDate,4,2))
lngDay = VAL(LEFT$($TargetDate,2))
FutureDate.NewDate(lngYear,lngMonth,lngDay)
'
' prep local vars to be used in date and time diff
LOCAL lngSign,lngYears, lngMonths, lngDays AS LONG
LOCAL lngHours, lngMinutes AS LONG
'
' calculate first part (years/months/days)
DateCalc.DateDiff(FutureDate, lngSign,lngYears, lngMonths, lngDays)
' prep the result for months & days
strResult = RIGHT$(" " & FORMAT$(lngMonths + (lngYears * 12)),2) & " " & _
RIGHT$(" " & FORMAT$(lngDays),2) & " "
'
' calculate second part (Days & hours & minutes)
DateCalc.TimeDiff(FutureDate, lngSign,lngDays,lngHours, lngMinutes)
'
' add on hours and minutes to result
strResult = strResult & RIGHT$(" " & FORMAT$(lngHours),2) & " " & _
RIGHT$(" " & FORMAT$(lngMinutes),2)
'
FUNCTION = strResult
'
END FUNCTION